/**
 * admui-basic v2.1.0 (http://www.admui.com/)
 * Copyright 2015-2019 Admui Team
 * Licensed under the Admui License 1.1 (http://www.admui.com/about/license)
 */
(function(window, document, $) {
  'use strict';

  window.App.extend({
    run: function() {
      //
      // Pipelining function for DataTables. To be used to the `ajax` option of DataTables
      //
      $.fn.dataTable.pipeline = function(opts) {
        // Configuration options
        var conf = $.extend(
          {
            pages: 5, // number of pages to cache
            url: 'http://demo.admui.com/employee/query', // script url
            data: null, // function or object with parameters to send to the server
            // matching how `ajax.data` works in DataTables
            method: 'GET', // Ajax HTTP method
            dataType: 'jsonp'
          },
          opts
        );

        // Private variables for storing the cache
        var cacheLower = -1;
        var cacheUpper = null;
        var cacheLastRequest = null;
        var cacheLastJson = null;

        return function(request, drawCallback, settings) {
          var ajax = false;
          var json;
          var requestStart = request.start;
          var drawStart = request.start;
          var requestLength = request.length;
          var requestEnd = requestStart + requestLength;
          var options = settings;
          var reqs = request;
          var d;

          if (options.clearCache) {
            // API requested that the cache be cleared
            ajax = true;
            options.clearCache = false;
          } else if (cacheLower < 0 || requestStart < cacheLower || requestEnd > cacheUpper) {
            // outside cached data - need to make a request
            ajax = true;
          } else if (
            JSON.stringify(request.order) !== JSON.stringify(cacheLastRequest.order) ||
            JSON.stringify(request.columns) !== JSON.stringify(cacheLastRequest.columns) ||
            JSON.stringify(request.search) !== JSON.stringify(cacheLastRequest.search)
          ) {
            // properties changed (ordering, columns, searching)
            ajax = true;
          }

          // Store the request for checking next time around
          cacheLastRequest = $.extend(true, {}, reqs);

          if (ajax) {
            // Need data from the server
            if (requestStart < cacheLower) {
              requestStart -= requestLength * (conf.pages - 1);

              requestStart = requestStart < 0 ? 0 : requestStart;
            }

            cacheLower = requestStart;
            cacheUpper = requestStart + requestLength * conf.pages;

            reqs.start = requestStart;
            reqs.length = requestLength * conf.pages;

            // Provide the same `data` options as DataTables.
            if ($.isFunction(conf.data)) {
              // As a function it is executed with the data object as an arg
              // for manipulation. If an object is returned, it is used as the
              // data object to submit
              d = conf.data(reqs);

              reqs = d === true ? $.extend(reqs, d) : reqs;
            } else if ($.isPlainObject(conf.data)) {
              // As an object, the data given extends the default
              $.extend(reqs, conf.data);
            }

            options.jqXHR = $.ajax({
              type: conf.method,
              url: conf.url,
              data: reqs,
              dataType: 'jsonp',
              cache: false,
              success: function(jsons) {
                cacheLastJson = $.extend(true, {}, jsons);

                if (cacheLower !== drawStart) {
                  jsons.data.splice(0, drawStart - cacheLower);
                }
                if (requestLength >= -1) {
                  jsons.data.splice(requestLength, jsons.data.length);
                }

                drawCallback(jsons);
              }
            });
          } else {
            json = $.extend(true, {}, cacheLastJson);
            json.draw = reqs.draw; // Update the echo for each response
            json.data.splice(0, requestStart - cacheLower);
            json.data.splice(requestLength, json.data.length);

            drawCallback(json);
          }
        };
      };

      // Register an API method that will empty the pipelined data, forcing an Ajax
      // fetch on the next draw (i.e. `table.clearPipeline().draw()`)
      $.fn.dataTable.Api.register('clearPipeline()', function() {
        return this.iterator('table', function(settings) {
          var sets = settings;
          sets.clearCache = true;
        });
      });

      //
      // DataTables initialisation
      //
      $('#dataTableExample').DataTable(
        $.concatCpt('dataTable', {
          processing: true,
          serverSide: true,
          ajax: $.fn.dataTable.pipeline({
            url: 'http://demo.admui.com/employee/query',
            dataType: 'jsonp',
            pages: 5 // number of pages to cache
          }),
          columns: [
            {data: 'name'},
            {data: 'title'},
            {data: 'base'},
            {data: 'age'},
            {data: 'hireDate'},
            {data: 'salary'}
          ]
        })
      );
    }
  });

  window.App.run();
})(window, document, jQuery);
